package com.ctu.autodial;

import java.io.DataOutputStream;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.log4j.Logger;

//import com.ctu.app.utils.LogUtil;
import com.ctu.autodial.util.CallRecord;
import com.ctu.autodial.util.SimulateEvent;
import com.ctu.autodial.util.CallRecord.CallResult;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * 拨打电话服务，用于拨打3个运营商的手机充值号码
 * 
 */
public class CallPhoneService extends Service {

	String mobile = "13800138000";
	public static boolean inCall = false;
	CallRecord callRecord;
	TelephonyManager manager;
	private static final String TAG = "CallPhoneService";
	private static final String EXCEPTION_FILE_NAME = "AutoDialRunException";
	long pre;
	boolean isCallRecharge = false;// 判断是否是进入充值流程后的挂机
	private static Logger runLogger;
	// **********测试*******************
	private boolean CALL_DEBUG = true;// false:进行调试

	// *********************************

	@Override
	public void onCreate() {
		super.onCreate();
		Log.i(TAG, "onCreate");
		pre = SystemClock.elapsedRealtime();
		runLogger = CrashApplication.getLoggerInstance();

		manager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
		manager.listen(new PhoneStateListenerImpl(),
				PhoneStateListener.LISTEN_CALL_STATE);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		Log.i(TAG, "onStart");

	}

	/**
	 * 拨打充值热线
	 */
	private void startCallRechargePhone() {

		isCallRecharge = true;
		inCall = true;
		// LogUtil.saveLog2File("拨通电话...");
		runLogger.info("拨通电话...");

		if (CALL_DEBUG) {
			Intent intent = new Intent("android.intent.action.CALL",
					Uri.parse("tel:" + "13800138000"));
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			startActivity(intent);
		}

	}

	/**
	 * 监听手机的状态
	 */
	class PhoneStateListenerImpl extends PhoneStateListener {
		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);

			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE:// 空闲

				if (inCall) {// 挂机
					if (isCallRecharge) {// 进入充值流程后挂机
						runLogger.info("充值客服挂机...isCallRecharge: "
								+ isCallRecharge);
						// LogUtil.saveLog2File("充值客服挂机...isCallRecharge: "
						// + isCallRecharge);

						Timer checkStatusTimer = new Timer();
						TimerTask checkStatusTask = new TimerTask() {
							@Override
							public void run() {
								checkRechageStatus();
								inCall = false;
							}
						};
						checkStatusTimer.schedule(checkStatusTask, 1 * 1000);
						isCallRecharge = false;
					} else {
						runLogger.info("非充值客服挂机...isCallRecharge: "
								+ isCallRecharge);
						// LogUtil.saveLog2File("非充值客服挂机...isCallRecharge: "
						// + isCallRecharge);
					}

				} else {
					runLogger.info("话机空闲中...inCall: " + inCall);
					// LogUtil.saveLog2File("话机空闲中...inCall: " + inCall);
				}
				break;

			case TelephonyManager.CALL_STATE_OFFHOOK:// 通话中
				if (isCallRecharge) {
					runLogger.info("充值通话中...inCall: " + inCall);
					// LogUtil.saveLog2File("充值通话中...inCall: " + inCall);
				} else {
					runLogger.info("非充值通话中...inCall: " + inCall);
					// LogUtil.saveLog2File("非充值通话中...inCall: " + inCall);
				}

				break;
			}
		}
	}

	/**
	 * 拨打语音电话
	 * 
	 * @param phone
	 *            手机号
	 * 
	 * @param pwd
	 *            卡密
	 */
	public void StartCall(final String phone, final String pwd) {
		runLogger.info("充值信息：mobile=" + phone + "," + "pwd=" + pwd);
		// LogUtil.saveLog2File("充值信息：mobile=" + phone + "," + "pwd=" + pwd);//
		// 保存日志

		startCallRechargePhone();

		if (CALL_DEBUG) {
			if (!inCall) {
				runLogger.info("拨打充值电话异常...inCall: " + inCall);
				// LogUtil.saveLog2File("拨打充值电话异常...inCall: " + inCall);
				return;
			}
		}

		final Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				runLogger.info("进入到充值流程线程...inCall: " + inCall);
				// LogUtil.saveLog2File("进入到充值流程线程...inCall: " + inCall);
				try {
					callRecord = new CallRecord(null);

					if (callRecord == null) {
						callRecord = new CallRecord(null);
					}

					try {
						callRecord.StartRecord(phone);
						// LogUtil.saveLog2File("开始录音");
						runLogger.info("开始录音");
					} catch (IllegalStateException e) {
						// LogUtil.saveLog2File("无法初始化录音组件" + e.getMessage());
						runLogger.info("无法初始化录音组件" + e.getMessage());

						callRecord.CancelRecord();
						Intent intent = new Intent(
								"com.ctu.autodial.callstatus");
						sendCallStatus(intent, 3);

					} catch (Exception e1) {
						
					}

					Thread.sleep(5 * 1000);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("将音量调到最大前...inCall: " +
							// inCall);
							runLogger.info("将音量调到最大前...inCall: " + inCall);

							return;
						}
					}

					// 将音量调到最大
					AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
					int maxVolume = audioManager
							.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
					audioManager.setMicrophoneMute(true);
					audioManager.setStreamVolume(
							AudioManager.STREAM_VOICE_CALL, maxVolume,
							AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
					int curVolume = audioManager
							.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
					if (maxVolume != curVolume) {
						Log.d("kaiz",
								"COULD NOT REACH MAX VOLUME!!!cur volume: "
										+ curVolume + " max: " + maxVolume);
					}
					// 打开键盘
					SimulateEvent.click(265, 350);

					// 选择语言，按1为普通话
					Thread.sleep(1 * 1000);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程通话异常断开------(选择语言前)---inCall: "
							// + inCall);
							runLogger.info("充值流程通话异常断开------(选择语言前)---inCall: "
									+ inCall);
							return;
						}
					}

					SimulateEvent.InputNumber(1);

					// 选择业务，按2为手机充值
					Thread.sleep(2 * 1000);
					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(选择业务前)---inCall: "
							// + inCall);
							runLogger.info("充值流程异常断开------(选择业务前)---inCall: "
									+ inCall);
							return;
						}
					}

					SimulateEvent.InputNumber(2);
					Thread.sleep(4 * 1000);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(输入充值手机号码前)---inCall: "
							// + inCall);
							runLogger
									.info("充值流程异常断开------(输入充值手机号码前)---inCall: "
											+ inCall);
							return;
						}
					}

					// 输入充值手机号码
					for (int i = 0; i < phone.length(); i++) {
						Thread.sleep(500);
						SimulateEvent.InputNumber(Character
								.getNumericValue(phone.charAt(i)));
					}

					// 输入#号键
					Thread.sleep(500);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(输入充值手机号#前)---inCall: "
							// + inCall);
							runLogger
									.info("充值流程异常断开------(输入充值手机号#前)---inCall: "
											+ inCall);
							return;
						}
					}

					SimulateEvent.InputNumber(12);
					Thread.sleep(25 * 1000);// 移动会随机延长或者缩短时间，保守起见延长时间

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(确认充值手机号码前)---inCall: "
							// + inCall);
							runLogger
									.info("充值流程异常断开------(确认充值手机号码前)---inCall: "
											+ inCall);
							return;
						}
					}
					// 按1确认充值手机号码
					SimulateEvent.InputNumber(1);
					Thread.sleep(4 * 1000);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(输入充值卡密码前)---inCall: "
							// + inCall);
							runLogger
									.info("充值流程异常断开------(输入充值卡密码前)---inCall: "
											+ inCall);
							return;
						}
					}
					// 输入充值卡密码
					for (int i = 0; i < pwd.length(); i++) {
						Thread.sleep(500);
						SimulateEvent.InputNumber(Character.getNumericValue(pwd
								.charAt(i)));
					}

					// 输入#号键
					Thread.sleep(500);

					if (CALL_DEBUG) {
						if (!inCall) {
							// LogUtil.saveLog2File("充值流程异常断开------(输入充值卡密码+#前)---inCall: "
							// + inCall);
							runLogger
									.info("充值流程异常断开------(输入充值卡密码+#前)---inCall: "
											+ inCall);
							return;
						}
					}
					SimulateEvent.InputNumber(12);

					callRecord.CheckResult();
					Thread.sleep(15 * 1000);

					if (CALL_DEBUG) {
						if (!inCall) {
							runLogger
									.info("充值流程异常断开------(AutoDial主动挂机前)---inCall: "
											+ inCall);
							// LogUtil.saveLog2File("充值流程异常断开------(AutoDial主动挂机前)---inCall: "
							// + inCall);
							return;
						}
					}

					inCall = false;

					SimulateEvent.click(160, 350);
					callRecord.SaveRecord();

					runLogger.info("AutoDial主动挂机了...inCall: " + inCall);
					// LogUtil.saveLog2File("AutoDial主动挂机了...inCall: " +
					// inCall);

					// // 判断是否已经运行了一个小时
					// // 如果是就先GC并且sleep30秒
					long now = SystemClock.elapsedRealtime();
					if ((now - pre) > (3600 * 1000)) {
						pre = now;
						runLogger.info("开始垃圾回收...");
						// LogUtil.saveLog2File("开始垃圾回收...");
						System.gc();
						Thread.sleep(30 * 1000);
						runLogger.info("结束垃圾回收...");
						// LogUtil.saveLog2File("结束垃圾回收...");
					}

					Thread.sleep(5 * 1000);
					checkRechageStatus();
					runLogger.info("AutoDial主动挂机后,返回充值状态值...");
					// LogUtil.saveLog2File("AutoDial主动挂机后,返回充值状态值...");

				} catch (Throwable e) {
					e.printStackTrace();
					runLogger.error("充值线程内部出现异常" + e, e);
					// LogUtil.saveExceptionLog2File(e, EXCEPTION_FILE_NAME);
				}
			}

		});
		thread.start();
	}

	/**
	 * 检测充值的状态
	 * 
	 * SUCCESS 成功 :0
	 * 
	 * INVALID_PWD 卡密失效（已经使用过）:1
	 * 
	 * WRONG_PWD 卡密不正确 :2
	 * 
	 * * ERROR 其它错误 :3
	 * 
	 * INVALID_PHONE 空号:4
	 * 
	 */
	private void checkRechageStatus() {
		Intent intent = new Intent("com.ctu.autodial.callstatus");
		CallResult result = callRecord.GetResult();
		switch (result) {
		case SUCCESS:
			sendCallStatus(intent, 0);
			break;

		case INVALID_PWD:
			sendCallStatus(intent, 1);
			break;

		case WRONG_PWD:
			sendCallStatus(intent, 2);
			break;

		case ERROR:
			sendCallStatus(intent, 3);
			break;

		case INVALID_PHONE:
			sendCallStatus(intent, 4);
			break;

		}

	}

	/**
	 * 发送充值的状态
	 * 
	 * @param intent
	 * @param callNum
	 */
	private void sendCallStatus(Intent intent, int callNum) {

		intent.putExtra("status", callNum);
		CallPhoneService.this.sendBroadcast(intent);
	}

	/**
	 * 给activity提供调用service中方法的接口
	 */
	CallPhoneServiceBinder mBinder = new CallPhoneServiceBinder();

	public class CallPhoneServiceBinder extends Binder {

		public CallPhoneService getService() {
			return CallPhoneService.this;
		}
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.i(TAG, "onDestroy");
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}

	@Override
	public void onLowMemory() {
		super.onLowMemory();
	}

	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}

	@Override
	public void onRebind(Intent intent) {
		super.onRebind(intent);
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "onBind");
		return mBinder;
	}

}
